// 引入登陆 退出 获取用户信息接口函数
import { login, logout, getInfo } from '@/api/user'
// 获取token 设置token 一出token函数
import { getToken, setToken, removeToken } from '@/utils/auth'
// 引入重置路由方法
import { resetRouter, anyRoutes, asyncRoutes, constantRoutes } from '@/router'
import router from '@/router'

const getDefaultState = () => {
    return {
        // 获取token
        token: getToken(),
        // 存储用户名字
        name: '',
        // 存储用户头像
        avatar: '',
        // 服务器返回菜单信息
        routes: [],
        // 按钮权限信息
        buttons: [],
        // 角色信息
        roles: [],
        // 对比后 项目中已有异步路由 和服务器返回数据对比最终展示的路由
        resultAsyncRoutes: [],
        // 用户最终需要展示的路由
        resultAllRoutes: []
    }
}

const state = getDefaultState()

// 修改state的地方
const mutations = {
    // 重置state Object.assign
    RESET_STATE: (state) => {
        Object.assign(state, getDefaultState())
    },
    // 存储token
    SET_TOKEN: (state, token) => {
        state.token = token
    },
    // 存储用户名
    SET_NAME: (state, name) => {
        state.name = name
    },
    // 存储头像
    SET_AVATAR: (state, avatar) => {
        state.avatar = avatar
    },
    // 存储用户信息
    SET_USERINFO: (state, userInfo) => {
        // 存储路由权限
        state.routes = userInfo.routes
            // 存储按钮权限
        state.buttons = userInfo.buttons
            // 存储角色信息
        state.roles = userInfo.roles
    },
    // 最终计算出的异步路由
    SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
        // Vuex保存当前用户的异步路由 用户需要展示完整路由还需整理
        state.resultAsyncRoutes = asyncRoutes
            // 计算需要展示的所有路由 concat()合并路由
        state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes, anyRoutes)
            // 给路由器添加新的路由
        router.addRoutes(state.resultAllRoutes)
    }
}

const actions = {
    // user login
    async login({ commit }, userInfo) {
        const { username, password } = userInfo
        // return new Promise((resolve, reject) => {
        //   login({ username: username.trim(), password: password }).then(response => {
        //     const { data } = response
        //     commit('SET_TOKEN', data.token)
        //     setToken(data.token)
        //     resolve()
        //   }).catch(error => {
        //     reject(error)
        //   })
        // })
        // 当前登陆采用mock数据 mock数据code为20000
        let result = await login({ username: username.trim(), password: password });
        // console.log(result)
        if (result.code == '20000') {
            // Vuex存储token
            commit('SET_TOKEN', result.data.token)
                // 本地持久化存储token信息
            setToken(result.data.token)
            return 'Login success'
        } else {
            return Promise.reject(new Error('Login failed'))
        }
    },

    // get user info
    getInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
            getInfo(state.token).then(response => {
                // 获取用户信息
                const { data } = response
                // console.log(data)
                // 返回数据包含用户名 头像 routes roles(角色) buttons(按钮信息)
                if (!data) {
                    return reject('Verification failed, please Login again.')
                }

                const { name, avatar } = data
                // Vuex存储用户全部信息
                commit('SET_USERINFO', data)
                commit('SET_NAME', name)
                commit('SET_AVATAR', avatar)
                    // 调用方法后返回的结果 传入mutations
                commit('SET_RESULTASYNCROUTES', computedAsyncRoutes(asyncRoutes, data.routes))
                resolve(data)
            }).catch(error => {
                reject(error)
            })
        })
    },

    // user logout
    logout({ commit, state }) {
        return new Promise((resolve, reject) => {
            logout(state.token).then(() => {
                removeToken() // must remove  token  first
                resetRouter()
                commit('RESET_STATE')
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },

    // remove token
    resetToken({ commit }) {
        return new Promise(resolve => {
            removeToken() // must remove  token  first
            commit('RESET_STATE')
            resolve()
        })
    }
}

// 定义函数两个数组进行对比 筛选出当前用户需要的路由 返回的即是resultAsyncRoutes
const computedAsyncRoutes = (asyncRoutes, routes) => {
    // console.log(asyncRoutes,routes)
    // 过滤出当前用户需要展示的数组
    return asyncRoutes.filter(item => {
        // console.log(item)
        // indexOf() == -1表示没有 !== -1展示
        if (routes.indexOf(item.name) !== -1) {
            // return item
            // 此处不能直接返回item 只能过滤一级路由 深层路由无法过滤
            // 需要采取递归操作
            if (item.children && item.children.length) {
                item.children = computedAsyncRoutes(item.children, routes)
            }
            // return true 当前遍历元素符合要求 返回出来
            return true
        }
    })
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}